package com.pine.common.util.tree;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;

import java.util.*;
import java.util.function.BiConsumer;

/**
 * 树形结构工具类
 *
 * @author pine manage
 * @since 2024-08-09
 */
public class TreeUtil {

    public static <TreeEntity extends TreeInfo<Long>> List<Tree<Long>> convertLongIdTree(List<TreeEntity> treeInfos, BiConsumer<Map<String, Object>, TreeEntity> biConsumer) {
        if (CollUtil.isEmpty(treeInfos)) {
            return Collections.emptyList();
        }

        long minId = treeInfos.stream().mapToLong(TreeEntity::getParentId).min().orElse(0L);
        return convert(treeInfos, minId, biConsumer);
    }

    public static <ID, TreeEntity extends TreeInfo<ID>> List<Tree<ID>> convert(List<TreeEntity> treeInfos, ID rootId, BiConsumer<Map<String, Object>, TreeEntity> biConsumer) {
        if (CollUtil.isEmpty(treeInfos)) {
            return Collections.emptyList();
        }

        List<TreeNode<ID>> treeNodes = new ArrayList<>();
        for (TreeEntity treeInfo : treeInfos) {
            TreeNode<ID> treeNode = new TreeNode<>();
            treeNode.setId(treeInfo.getId());
            treeNode.setName(treeInfo.getName());
            treeNode.setParentId(treeInfo.getParentId());
            treeNode.setWeight(treeInfo.getWeight());

            // 扩展字段
            if (Objects.nonNull(biConsumer)) {
                Map<String, Object> extra = new LinkedHashMap<>();
                biConsumer.accept(extra, treeInfo);
                treeNode.setExtra(extra);
            }
            treeNodes.add(treeNode);
        }

        return cn.hutool.core.lang.tree.TreeUtil.build(treeNodes, rootId);
    }
}
